package world;

import java.util.HashMap;
import java.util.HashSet;

import packets.SPacket;

import entities.Entity;
import entities.Player;
import exceptions.MCConnectionException;

import network.MCConnection;

/**
 * This class will keep track of all connected clients in the world.
 * 
 * When a new client connects:
 *   1. it will inform all currently connected clients of the new player.
 *   2. it will inform the logging in player with all known entities.
 *   
 * When a client disconnects, it will inform all other clients of the leaving player.
 *
 */
public final class ConnectionManager extends WorldStateMonitor {
	
	private HashSet<MCConnection> connections = new HashSet<MCConnection>();
	private HashMap<Player, MCConnection> playerconnections = new HashMap<Player, MCConnection>();

	
	public ConnectionManager(WorldState state) {
		super(state);
	}

	
	
	public synchronized void addPlayer(MCConnection conn) {
		this.connections.add(conn);
		this.playerconnections.put(conn.getPlayer(), conn);
	}
	
	
	public synchronized  void removePlayer(MCConnection conn) {
		Player player = conn.getPlayer();
		this.connections.remove(conn);
		this.playerconnections.remove(player);

	}
	
	
	/**
	 * Sends a certain packet to a player.
	 * @param player
	 * @param p
	 * @throws MCConnectionException
	 */
	public void sendPacketTo(Player player, SPacket p) throws MCConnectionException {
		playerconnections.get(player).send(p);
	}
	
	
	/**
	 * Send a packet to all connected people, except for one.
	 * @param p
	 * @param entity
	 */
	public void sendPacketToAllOthers(SPacket p, Entity player) {
		for(MCConnection c : connections) {
			try {
				if(c.getPlayer() != player) {
					c.send(p);
				}
			} catch (MCConnectionException e) {}
		}
	}
	
	/**
	 * Sends a packet to all players.
	 * @param p
	 */
	public void sendPacketToAll(SPacket p) {
		for(MCConnection c : connections) {
			try {
				c.send(p);
			} catch (MCConnectionException e) {}
		}
	}
	
}
